<?php
namespace Sms\src;
use Exception;

/**
 * 三通批量短信发送
 * Class SanTong
 * @package Sms\src
 */
class SanTong implements \Sms\Smsinf
{
    protected $url_base = 'http://www.dh3t.com/json/sms' ;
    protected $base_data ;
    protected $is_Arrears;
    protected $data ;

    protected $disable ;

    protected $notable_code = [
        1,2,9,11,19,20,97
    ];

    /**
     * 提交返回错误码对照
     * @var array
     */
    protected $commit_code = [
        0  => '提交成功',
        1  => '账号无效',
        2  => '密码错误',
        3  => 'msgid太长，不得超过64位',
        4  => '错误号码/限制运营商号码',
        5  => '手机号码个数超过最大限制',
        6  => '短信内容超过最大限制',
        7  => '扩展子号码无效',
        8  => '定时时间格式错误',
        14 => '手机号码为空',
        19 => '用户被禁发或禁用',
        20 => 'ip鉴权失败',
        21 => '短信内容为空',
        22 => '数据包大小不匹配',
        23 => 'taskid太长',
        24 => '无可用号码',
        25 => '批量提交短信数超过最大限制',
        98 => '系统正忙',
        99 => '消息格式错误',
        'http404'=>'网络异常',
    ];
    /**
     * 获取状态返回错误码对照
     * @var array
     */
    protected $get_code = [
        0 =>"发送成功",
        4  => '手机号码无效',
        5  => '签名不合法',
        6  => '短信内容超过最大限制',
        9  => '请求来源地址无效',
        10 => '内容包含敏感词',
        11 => '余额不足',
        12 => '购买产品或订购还未生效或产品已暂停使用',
        13 => '账号被禁用或禁发',
        14 => '不支持该运营商',
        16 => '发送号码数没有达到该产品的最小发送数',
        19 => '黑名单号码',
        20 => '该模板ID已被禁用',
        21 => '非法模板ID',
        22 => '不支持的MSGFMT',
        23 => '子号码无效',
        24 => '内容为空',
        25 => '号码为空',
        26 => '单个号码相同内容限制',
        27 => '单个号码次数限制',
        28 => '账号被拦截，不允许发送',
        96 => '处理失败',
        97 => '接入方式错误',
        98 => '系统繁忙',
        99 => '消息格式错误',
        'http404'=>'网络异常'
    ];

    public function __construct($type,$account)
    {
        $this->base_data['account'] = $account['account'];
        $this->base_data['password'] = md5($account['password']);
    }

    /**
     *
     * @return mixed|void
     */
    /**
     * 获取发送结果
     * @return array|bool|mixed
     */
    public function getSendStatus()
    {
        $data = $this->base_data ;
        $res = $this->request($data,$this->url_base.'/Report');
        if(!$res['result'])
        {
            if(!empty($res['reports']))
            {
                $data = [] ;
                foreach($res['reports'] as $v)
                {
                    $data[] = array(
                        'msgid'=>$v['msgid'],
                        'phone'=>$v['phone'],
                        'status'=>$v['status'],
                        'desc'=>$v['desc']?:$this->get_code[$v['status']],
                        'code'=>$v['wgcode'],
                    );
                }
                return $data ;
            }
            else
            {
                return false ;
            }
        }
        else
        {
            return false ;
        }
    }

    /**
     * @return array|bool
     */
    public function balanceQuery()
    {
        $data = $this->base_data ;
        $res = $this->request($data,$this->url_base.'/Balance');
        if(!$res['result'])
        {
            if(!empty($res['smsBalance']))
            {
                return array('num'=>$res['smsBalance']['number'],'amount'=>$res['smsBalance']['amount']);
            }
            else
            {
                return false ;
            }
        }
        else
        {
            return false ;
        }
    }

    /**
     * @param $to
     * @param $content
     * @param bool $sign
     * @return array|mixed
     */
    public function send($to, $content,$sign=false)
    {
        $this->data = $this->base_data;
        $this->data['msgid'] = $this->createMsgId();
        $this->data['content'] = $content;
        $this->data['sign'] = $sign;
        $this->data['sendtime'] = date('YmdHi');
        $this->data['phones'] = $to;
        $res = $this->request($this->toString($this->data),$this->url_base.'/Submit');
        if(in_array($res['result'],$this->notable_code))
        {
            $this->disable = 1 ;
        }
        else{
            $this->disable = 0 ;
        }
        return array('error'=>$res['result'],'info'=>$res['desc'],'msgid'=>$this->data['msgid'],'content'=>$content);
    }

    /**
     * 批量短信接口
     * @param array $data | data = array( $to => $content,$to1 = $content )
     * @throws Exception
     */
    public function batchSend( array $data )
    {
        $this->data = $this->base_data;
        $num = count($data ) ;
        if($num>500)
        {
            throw new Exception('can not more 500! ');
        }
    }

    /**
     * 是否可以继续发送
     * @return mixed
     */
    public function isArrears()
    {
        return $this->disable ;
    }

    /**
     * 创建消息id
     * @return string
     */
    protected function createMsgId()
    {
        return md5(uniqid('St',true).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9).mt_rand(0,9));
    }

    /**
     * @param $arr
     * @return array|string
     */
    protected function toString($arr)
    {
        if(is_array($arr))
        {
            foreach($arr as $k=>$v)
            {
                $arr[(string)$k] = $this->toString($v);
            }
            return $arr ;
        }
        else{
            return (string)$arr ;
        }
    }

    /**
     * @param $data
     * @param $url
     * @return string
     */
    protected function request($data,$url)
    {
        try{
            $data = json_encode($data);
            $ch = curl_init ( $url );
            curl_setopt ( $ch, CURLOPT_POST, 1 );
            curl_setopt ( $ch, CURLOPT_HEADER, 0 );
            curl_setopt ( $ch, CURLOPT_FRESH_CONNECT, 1 );
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
            curl_setopt ( $ch, CURLOPT_FORBID_REUSE, 1 );
            curl_setopt ( $ch, CURLOPT_TIMEOUT, 30 );
            curl_setopt ( $ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen ( $data ) ) );
            curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
            $ret = curl_exec ( $ch );
            if(curl_errno($ch))
            {
                throw new \Exception(curl_error($ch));
            }
            $ret = json_decode(trim($ret),true);
        }
        catch(Exception $e)
        {
            $ret = array('msgid'=>'0','result'=>'http404','desc'=>$e->getMessage(),'failPhones'=>'');
        }
        curl_close ( $ch );
        return $ret;
    }
}